// locutor
// (c) 2008-2009, Normen Müller, normen.mueller@gmail.com  
// $Id: RegistrySpecUpdate.scala 2451 2009-10-01 14:04:14Z nmueller $
package locutor.spec.registry

import org.specs._

import java.io.File
import scaup.Views._
import scala.xml.XML
import scaup.io.FileType._
import scaup.data.Conversions._
import locutor.registry._
import locutor.spec.Util._

object RegistrySpecUpdate extends Specification("Update") {
  def throwWarnings = addToSusVerb("throw warnings due to")
  "Update" should throwWarnings {
    "working copy is not registered" in {
      ioMkDir("wca")
      val exts = new java.util.LinkedList[String]()
      newRegistry().update(WCA,"".toFile,exts) must throwA[RegistryWarning]
    }
  }
  
  
  def notModify = addToSusVerb("not modify the registry nor the working copy due to")
  "Update" should notModify {
    "redundant changes on externals definitions" in {
      setupWC("wcb")

      val r = newRegistry()
      r.insert(WCB)
      r.serialize()
      
      val xml =
        (<registry version="0.1" xmlns="http://locutor.kwarc.info">
           <wc xml:id={WCB.path.toMD5} url={URLB} root={WCB.path}>
             <external xml:id={(WCB/"a").path.toMD5} own={WCB.path} rev="-1" url={URLA} tgt="a"/>
           </wc>
         </registry>)
      
      XML.loadFile(REG) must ==/(xml)
      /* =========================================================================================== */
      /* Here we fake; svnCommit will be locutorCommit */
      val exts = new java.util.LinkedList[String]()
      exts.add("https://svn.kwarc.info/repos/sandbox/wca a")
      r.update(WCB, WCB, exts)
      r.serialize()
      /* =========================================================================================== */      
      XML.loadFile(REG) must ==/(xml)
    }
  }

  
  def extendWC = addToSusVerb("extend a working copy by")
  "Update" should extendWC {
    "recently committed externals (1st example)" in {
      setupWC("wca")

      val r = newRegistry()
      r.insert(WCA)
      
      svnSetExternal("wca/a", (-1, "https://svn.kwarc.info/repos/sandbox/wcb", "b"))
      /* =========================================================================================== */
      /* Here we fake; svnCommit will be locutorCommit */
      svnCommit("wca", "")      
      val exts = new java.util.LinkedList[String]()
      exts.add("https://svn.kwarc.info/repos/sandbox/wcb b")      
      r.update(WCA, (WCA/"a"), exts)
      r.serialize()
      /* =========================================================================================== */
      XML.loadFile(REG) must ==/(
        (<registry version="0.1" xmlns="http://locutor.kwarc.info">
           <wc xml:id={WCA.path.toMD5} url={URLA} root={WCA.path}>
             <external xml:id={(WCA/"a/b").path.toMD5} own={(WCA/"a").path} rev="-1" url={URLB} tgt="b"/>
           </wc>
         </registry>))      
    }
    "recently committed externals (2nd example)" in {
      setupWC("wca")
      
      var r = newRegistry()
      r.insert(WCA)
      
      svnSetExternal("wca", (-1, "https://svn.kwarc.info/repos/sandbox/wca", "b/a"))
      /* =========================================================================================== */
      /* Here we fake; svnCommit will be locutorCommit */
      svnCommit("wca", "")
      val exts = new java.util.LinkedList[String]()
      exts.add("https://svn.kwarc.info/repos/sandbox/wca b/a")
      r.update(WCA, WCA, exts)
      r.serialize()
      /* =========================================================================================== */
      XML.loadFile(REG) must ==/(
        (<registry version="0.1" xmlns="http://locutor.kwarc.info">
           <wc xml:id={WCA.path.toMD5} url={URLA} root={WCA.path}>
             <external xml:id={(WCA/"b/a").path.toMD5} own={WCA.path} rev="-1" url={URLA} tgt="b/a" xref={"#"+WCA.path.toMD5}/>
           </wc>
         </registry>))
      (WCA/"b/a").t must_== SYMLINK
      (WCA/"b/a").lnktgt must_== Some(WCA.path)      
    }
    "recently committed externals (3rd example)" in {
      setupWC("wcb")      

      val r = newRegistry()
      r.insert(WCB)
      
      svnSetExternal("wcb/b", (-1, "https://svn.kwarc.info/repos/sandbox/wcc", "c"))
      /* =========================================================================================== */
      /* Here we fake; svnCommit will be locutorCommit */
      svnCommit("wcb/b", "")
      val exts = new java.util.LinkedList[String]()
      exts.add("https://svn.kwarc.info/repos/sandbox/wcc c")
      r.update(WCB, WCB/"b", exts)
      r.serialize()
      /* =========================================================================================== */
      XML.loadFile(REG) must ==/(
        (<registry version="0.1" xmlns="http://locutor.kwarc.info">
           <wc xml:id={WCB.path.toMD5} url={URLB} root={WCB.path}>
             <external xml:id={(WCB/"a").path.toMD5} own={WCB.path} rev="-1" url={URLA} tgt="a"/>
             <external xml:id={(WCB/"b/c").path.toMD5} own={(WCB/"b").path} rev="-1" url={URLC} tgt="c"/>
           </wc>
         </registry>))
    }
    "recently committed externals (4th example)" in {
      setupWC("wca")
      setupWC("wcb")

      val r = newRegistry()
      r.insert(WCA)
      r.insert(WCB)
      
      svnSetExternal("wca/a", (-1, "https://svn.kwarc.info/repos/sandbox/wcb", "b"))
      /* =========================================================================================== */
      /* Here we fake; svnCommit will be locutorCommit */
      svnCommit("wca", "")      
      val exts = new java.util.LinkedList[String]()
      exts.add("https://svn.kwarc.info/repos/sandbox/wcb b")      
      r.update(WCA, (WCA/"a"), exts)
      r.serialize()
      /* =========================================================================================== */
      XML.loadFile(REG) must ==/(
        (<registry version="0.1" xmlns="http://locutor.kwarc.info">
           <wc xml:id={WCA.path.toMD5} url={URLA} root={WCA.path}>
             <external xml:id={(WCA/"a/b").path.toMD5} own={(WCA/"a").path} rev="-1" url={URLB} tgt="b" xref={"#"+WCB.path.toMD5}/>
           </wc>
           <wc xml:id={WCB.path.toMD5} url={URLB} root={WCB.path}>
             <external xml:id={(WCB/"a").path.toMD5} own={WCB.path} rev="-1" url={URLA} tgt="a"/>
           </wc>
         </registry>))      
    }                                                                                            
  }
  
  
  def remove = addToSusVerb("remove")
  "Update" should remove {
    "all externals no longer in definition space (1st example)" in {
      setupWC("wcb")      

      val r = newRegistry()
      r.insert(WCB)
      
      svnSetExternal("wcb", (-1, "https://svn.kwarc.info/repos/sandbox/wcc", "b/c"))
      /* =========================================================================================== */
      /* Here we fake; svnCommit will be locutorCommit */
      svnCommit("wcb", "")
      val exts = new java.util.LinkedList[String]()
      exts.add("https://svn.kwarc.info/repos/sandbox/wcc b/c")
      r.update(WCB, WCB, exts)
      r.serialize()
      /* =========================================================================================== */
      XML.loadFile(REG) must ==/(
        (<registry version="0.1" xmlns="http://locutor.kwarc.info">
           <wc xml:id={WCB.path.toMD5} url={URLB} root={WCB.path}>
             <external xml:id={(WCB/"b/c").path.toMD5} own={WCB.path} rev="-1" url={URLC} tgt="b/c"/>
           </wc>
         </registry>))      
    }
    "all externals no longer in definition space (2nd example)" in {
      setupWC("wca")
      setupWC("wcf")
      setupWC("wcg")
      svnUpdate("wcf")

      val r = newRegistry()
      r.insert(WCA)
      r.insert(WCF)
      r.insert(WCG)
      r.sanitize(WCG)
      
      svnSetExternal("wcg", (-1, "", ""))
      /* =========================================================================================== */
      /* Here we fake; svnCommit will be locutorCommit */
      svnCommit("wcg", "")
      val exts = new java.util.LinkedList[String]()
      r.update(WCG, WCG, exts)
      r.serialize()
      /* =========================================================================================== */
      XML.loadFile(REG) must ==/(
        (<registry version="0.1" xmlns="http://locutor.kwarc.info">
           <wc xml:id={WCA.path.toMD5} url={URLA} root={WCA.path}/>
           <wc xml:id={WCF.path.toMD5} url={URLF} root={WCF.path}>
             <external xml:id={(WCF/"a").path.toMD5} own={WCF.path} rev="-1" url={(URLA.toURI/"a").toString} tgt="a"/>
             <external xml:id={(WCF/"b").path.toMD5} own={WCF.path} rev="-1" url={(URLA.toURI/"b").toString} tgt="b"/>
           </wc>
           <wc xml:id={WCG.path.toMD5} url={URLG} root={WCG.path}/>
         </registry>))
    }
    "all externals no longer in definition space (3rd example)" in {
      setupWC("wca")
      setupWC("wcf")
      setupWC("wcg")
      svnUpdate("wcf")

      val r = newRegistry()
      r.insert(WCA)
      r.insert(WCF)
      r.insert(WCG)
      r.sanitize(WCG)
      
      svnSetExternal("wcf", (-1, "", ""))
      /* =========================================================================================== */
      /* Here we fake; svnCommit will be locutorCommit */
      svnCommit("wcf", "")
      val exts = new java.util.LinkedList[String]()
      r.update(WCF, WCF, exts)
      r.serialize()
      /* =========================================================================================== */
      XML.loadFile(REG) must ==/(
        (<registry version="0.1" xmlns="http://locutor.kwarc.info">
           <wc xml:id={WCA.path.toMD5} url={URLA} root={WCA.path}/>
           <wc xml:id={WCF.path.toMD5} url={URLF} root={WCF.path}/>
           <wc xml:id={WCG.path.toMD5} url={URLG} root={WCG.path}>
             <external xml:id={(WCG/"a").path.toMD5} own={WCG.path} rev="-1" url={URLF} tgt="a" xref={"#"+WCF.path.toMD5}/>
           </wc>
         </registry>))
      
      svnSetExternal("wcg", (-1, "", ""))
      /* =========================================================================================== */
      /* Here we fake; svnCommit will be locutorCommit */
      svnCommit("wcg", "")
      r.update(WCG, WCG, exts)
      r.serialize()
      /* =========================================================================================== */
      XML.loadFile(REG) must ==/(
        (<registry version="0.1" xmlns="http://locutor.kwarc.info">
           <wc xml:id={WCA.path.toMD5} url={URLA} root={WCA.path}/>
           <wc xml:id={WCF.path.toMD5} url={URLF} root={WCF.path}/>
           <wc xml:id={WCG.path.toMD5} url={URLG} root={WCG.path}/>
         </registry>))      
    }
    "all externals no longer in definition space and resolve dependents (1st example)" in {
      setupWC("wcb")
      setupWC("wce")
      
      var r = newRegistry()
      r.insert(WCB)
      r.insert(WCE)
      r.sanitize(WCE)
      
      svnSetExternal("wcb", (-1, "", ""))
      /* =========================================================================================== */
      /* Here we fake; svnCommit will be locutorCommit */
      svnCommit("wcb", "")
      val exts = new java.util.LinkedList[String]()
      r.update(WCB, WCB, exts)
      r.serialize()
      /* =========================================================================================== */      
      XML.loadFile(REG) must ==/(
        (<registry version="0.1" xmlns="http://locutor.kwarc.info">
           <wc xml:id={WCB.path.toMD5} url={URLB} root={WCB.path}/>
           <wc xml:id={WCE.path.toMD5} url={URLE} root={WCE.path}>
             <external xml:id={(WCE/"a").path.toMD5} own={WCE.path} rev="-1" url={URLA} tgt="a"/>
           </wc>
         </registry>))
      (WCE/"a").t must_== NONE
      (WCE/"a") mustNot exist      
    }
    "all externals no longer in definition space and resolve dependents (2nd example)" in {
      setupWC("wca")
      setupWC("wcb")
      setupWC("wce")
      svnUpdate("wcb")
      
      var r = newRegistry()
      r.insert(WCB)
      r.insert(WCE)
      r.sanitize(WCE)
      r.insert(WCA)
      r.serialize()
      
      XML.loadFile(REG) must ==/(
        (<registry version="0.1" xmlns="http://locutor.kwarc.info">
           <wc xml:id={WCA.path.toMD5} url={URLA} root={WCA.path}/>
           <wc xml:id={WCB.path.toMD5} url={URLB} root={WCB.path}>
             <external xml:id={(WCB/"a").path.toMD5} own={WCB.path} rev="-1" url={URLA} tgt="a"/>
           </wc>
           <wc xml:id={WCE.path.toMD5} url={URLE} root={WCE.path}>
             <external xml:id={(WCE/"a").path.toMD5} own={WCE.path} rev="-1" url={URLA} tgt="a" xref={"#"+(WCB/"a").path.toMD5}/>
           </wc>
         </registry>))
      
      svnSetExternal("wcb", (-1, "", ""))
      /* =========================================================================================== */
      /* Here we fake; svnCommit will be locutorCommit */
      svnCommit("wcb", "")
      val exts = new java.util.LinkedList[String]()
      r.update(WCB, WCB, exts)
      r.serialize()
      /* =========================================================================================== */      
      XML.loadFile(REG) must ==/(
        (<registry version="0.1" xmlns="http://locutor.kwarc.info">
           <wc xml:id={WCA.path.toMD5} url={URLA} root={WCA.path}/>
           <wc xml:id={WCB.path.toMD5} url={URLB} root={WCB.path}/>
           <wc xml:id={WCE.path.toMD5} url={URLE} root={WCE.path}>
             <external xml:id={(WCE/"a").path.toMD5} own={WCE.path} rev="-1" url={URLA} tgt="a" xref={"#"+WCA.path.toMD5}/>
           </wc>
         </registry>))
      (WCE/"a").t must_== SYMLINK
      (WCE/"a").lnktgt must_== Some(WCA.path)
    }
    "all externals no longer in definition space and resolve dependents (3rd example)" in {
      setupWC("wca")
      setupWC("wcb")
      setupWC("wce")
      
      var r = newRegistry()
      r.insert(WCA)
      r.insert(WCB)
      r.insert(WCE)
      r.sanitize(WCE)
      r.serialize()
      
      XML.loadFile(REG) must ==/(
        (<registry version="0.1" xmlns="http://locutor.kwarc.info">
           <wc xml:id={WCA.path.toMD5} url={URLA} root={WCA.path}/>
           <wc xml:id={WCB.path.toMD5} url={URLB} root={WCB.path}>
             <external xml:id={(WCB/"a").path.toMD5} own={WCB.path} rev="-1" url={URLA} tgt="a"/>
           </wc>
           <wc xml:id={WCE.path.toMD5} url={URLE} root={WCE.path}>
             <external xml:id={(WCE/"a").path.toMD5} own={WCE.path} rev="-1" url={URLA} tgt="a" xref={"#"+WCA.path.toMD5}/>
           </wc>
         </registry>))
      
      svnSetExternal("wcb", (-1, "", ""))
      /* =========================================================================================== */
      /* Here we fake; svnCommit will be locutorCommit */
      svnCommit("wcb", "")
      val exts = new java.util.LinkedList[String]()
      r.update(WCB, WCB, exts)
      r.serialize()
      /* =========================================================================================== */      
      XML.loadFile(REG) must ==/(
        (<registry version="0.1" xmlns="http://locutor.kwarc.info">
           <wc xml:id={WCA.path.toMD5} url={URLA} root={WCA.path}/>
           <wc xml:id={WCB.path.toMD5} url={URLB} root={WCB.path}/>
           <wc xml:id={WCE.path.toMD5} url={URLE} root={WCE.path}>
             <external xml:id={(WCE/"a").path.toMD5} own={WCE.path} rev="-1" url={URLA} tgt="a" xref={"#"+WCA.path.toMD5}/>
           </wc>
         </registry>))
      (WCE/"a").t must_== SYMLINK
      (WCE/"a").lnktgt must_== Some(WCA.path)
    }
  }

  
  def adapt = addToSusVerb("adapt")
  "Update" should adapt {
    "externals wrt. revision" in {
      setupWC("wcb")
      svnSetExternal("wcb/b", (-1, "https://svn.kwarc.info/repos/sandbox/wcc", "c"))
      svnCommit("wcb/b", "")

      val r = newRegistry()
      r.insert(WCB)
      
      /* =========================================================================================== */
      /* Here we fake; svnCommit will be locutorCommit */
      val exts = new java.util.LinkedList[String]()
      exts.add("-r 4490 https://svn.kwarc.info/repos/sandbox/wca a")
      r.update(WCB, WCB, exts)
      r.serialize()
      /* =========================================================================================== */
      XML.loadFile(REG) must ==/(
        (<registry version="0.1" xmlns="http://locutor.kwarc.info">
           <wc xml:id={WCB.path.toMD5} url={URLB} root={WCB.path}>
             <external xml:id={(WCB/"a").path.toMD5} own={WCB.path} rev="4490" url={URLA} tgt="a"/>
             <external xml:id={(WCB/"b/c").path.toMD5} own={(WCB/"b").path} rev="-1" url={URLC} tgt="c"/>
           </wc>
         </registry>))
    }
    "externals wrt. URL" in {
      setupWC("wcb")
      svnSetExternal("wcb/b", (-1, "https://svn.kwarc.info/repos/sandbox/wcc", "c"))
      svnCommit("wcb/b", "")

      val r = newRegistry()
      r.insert(WCB)
      /* =========================================================================================== */
      /* Here we fake; svnCommit will be locutorCommit */
      val exts = new java.util.LinkedList[String]()
      exts.add("https://svn.kwarc.info/repos/demos a")
      r.update(WCB, WCB, exts)
      r.serialize()
      /* =========================================================================================== */
      XML.loadFile(REG) must ==/(
        (<registry version="0.1" xmlns="http://locutor.kwarc.info">
           <wc xml:id={WCB.path.toMD5} url={URLB} root={WCB.path}>
             <external xml:id={(WCB/"a").path.toMD5} own={WCB.path} rev="-1" url="https://svn.kwarc.info/repos/demos" tgt="a"/>
             <external xml:id={(WCB/"b/c").path.toMD5} own={(WCB/"b").path} rev="-1" url={URLC} tgt="c"/>
           </wc>
         </registry>))
    }
    "transexs wrt. revision (1st example)" in {
      setupWC("wcb")
      setupWC("wce")
      svnUpdate("wcb")
      
      var r = newRegistry()
      r.insert(WCB)
      r.insert(WCE)
      r.sanitize(WCE)
      
      svnSetExternal("wcb", (4490, "https://svn.kwarc.info/repos/sandbox/wca", "a"))
      /* =========================================================================================== */
      /* Here we fake; svnCommit will be locutorCommit */
      svnCommit("wcb", "")
      val exts = new java.util.LinkedList[String]()
      exts.add("-r 4490 https://svn.kwarc.info/repos/sandbox/wca a")
      r.update(WCB, WCB, exts)
      r.serialize()
      /* =========================================================================================== */      
      /* REASSESS:  In such a case a locutor commit could not only modify registry entry of wcb
       * but also re-transform depending transformed externals.  Here that would mean, wcc/a is
       * re-transformed in sense of the symbolic link is deleted and the respective registry entry is
       * updated.
       * CONCLUSION: A locutor commit /does/ not only modify registry entry of wcb
       * but also re-transforms depending transformed externals.  Note that, the appoach a
       * commit re-transforming depending transexs is more user friendly and save, in sense of
       * the user does not have to remember to re-sanitize depending working copies. */
      XML.loadFile(REG) must ==/(
        (<registry version="0.1" xmlns="http://locutor.kwarc.info">
           <wc xml:id={WCB.path.toMD5} url={URLB} root={WCB.path}>
             <external xml:id={(WCB/"a").path.toMD5} own={WCB.path} rev="4490" url={URLA} tgt="a"/>
           </wc>
           <wc xml:id={WCE.path.toMD5} url={URLE} root={WCE.path}>
             <external xml:id={(WCE/"a").path.toMD5} own={WCE.path} rev="-1" url={URLA} tgt="a"/>
           </wc>
         </registry>))
      /* No retransform of wce/a due to revision inequality. */
      (WCE/"a").t must_== NONE
      (WCE/"a") mustNot exist      
    }
    "transexs wrt. revision (2nd example)" in {
      setupWC("wca")
      setupWC("wcb")
      setupWC("wce")
      svnUpdate("wcb")
            
      var r = newRegistry()
      r.insert(WCB)
      r.insert(WCE)
      r.sanitize(WCE)
      r.insert(WCA)
      
      svnSetExternal("wcb", (4490, "https://svn.kwarc.info/repos/sandbox/wca", "a"))
      /* =========================================================================================== */
      /* Here we fake; svnCommit will be locutorCommit */
      svnCommit("wcb", "")
      val exts = new java.util.LinkedList[String]()
      exts.add("-r 4490 https://svn.kwarc.info/repos/sandbox/wca a")
      r.update(WCB, WCB, exts)
      r.serialize()
      /* =========================================================================================== */
      
      XML.loadFile(REG) must ==/(
        (<registry version="0.1" xmlns="http://locutor.kwarc.info">
           <wc xml:id={WCA.path.toMD5} url={URLA} root={WCA.path}/>
           <wc xml:id={WCB.path.toMD5} url={URLB} root={WCB.path}>
             <external xml:id={(WCB/"a").path.toMD5} own={WCB.path} rev="4490" url={URLA} tgt="a"/>
           </wc>
           <wc xml:id={WCE.path.toMD5} url={URLE} root={WCE.path}>
             <external xml:id={(WCE/"a").path.toMD5} own={WCE.path} rev="-1" url={URLA} tgt="a" xref={"#"+WCA.path.toMD5}/>
           </wc>
         </registry>))
      (WCE/"a").t must_== SYMLINK
      (WCE/"a").lnktgt must_== Some(WCA.path)      
    }
    "transexs wrt. URL (1st example)" in {
      setupWC("wca")
      setupWC("wcb")

      val r = newRegistry()
      r.insert(WCA)
      r.insert(WCB)
      r.sanitize(WCB)

      svnSetExternal("wcb", (-1, "https://svn.kwarc.info/repos/sandbox/wca/a", "a"))
      /* =========================================================================================== */
      /* Here we fake; svnCommit will be locutorCommit */      
      svnCommit("wcb", "")
      val exts = new java.util.LinkedList[String]()
      exts.add("https://svn.kwarc.info/repos/sandbox/wca/a a")
      r.update(WCB, WCB, exts)
      r.serialize()      
      /* =========================================================================================== */
      XML.loadFile(REG) must ==/(         
        (<registry version="0.1" xmlns="http://locutor.kwarc.info">
           <wc xml:id={WCA.path.toMD5} url={URLA} root={WCA.path}/>
           <wc xml:id={WCB.path.toMD5} url={URLB} root={WCB.path}>
             <external xml:id={(WCB/"a").path.toMD5} own={WCB.path} rev="-1" url={(URLA.toURI/"a").toString} tgt="a" xref={"#"+WCA.path.toMD5}/>
           </wc>
         </registry>))
      (WCB/"a").t must_== SYMLINK
      (WCB/"a").lnktgt must_== Some((WCA/"a").path)
    }
    "transexs wrt. URL (2nd example)" in {
      setupWC("wca")
      setupWC("wcb")
      
      val r = newRegistry()
      r.insert(WCA)
      r.insert(WCB)
      r.sanitize(WCB)
      r.serialize()
      
      val xml =
        (<registry version="0.1" xmlns="http://locutor.kwarc.info">
           <wc xml:id={WCA.path.toMD5} url={URLA} root={WCA.path}/>
           <wc xml:id={WCB.path.toMD5} url={URLB} root={WCB.path}>
             <external xml:id={(WCB/"a").path.toMD5} own={WCB.path} rev="-1" url={URLA} tgt="a" xref={"#"+WCA.path.toMD5}/>
           </wc>
         </registry>)
      
      XML.loadFile(REG) must ==/(xml)
      (WCB/"a").t must_== SYMLINK
      (WCB/"a").lnktgt must_== Some(WCA.path)
      
      ioRemove("wcb/a")
      svnSetExternal("wcb", (-1, "https://svn.kwarc.info/repos/sandbox/wca/a", "a"))
      
      /* Here the state is reset */
      r.sanitize(WCB)
      r.serialize()
      
      XML.loadFile(REG) must ==/(xml)         
      (WCB/"a").t must_== SYMLINK
      (WCB/"a").lnktgt must_== Some(WCA.path)
      
      /* =========================================================================================== */
      /* Here we fake; svnCommit will be locutorCommit */
      svnCommit("wcb", "")
      val exts = new java.util.LinkedList[String]()
      exts.add("https://svn.kwarc.info/repos/sandbox/wca/a a")
      r.update(WCB, WCB, exts)
      r.serialize()
      /* =========================================================================================== */
      XML.loadFile(REG) must ==/(         
        (<registry version="0.1" xmlns="http://locutor.kwarc.info">
           <wc xml:id={WCA.path.toMD5} url={URLA} root={WCA.path}/>
           <wc xml:id={WCB.path.toMD5} url={URLB} root={WCB.path}>
             <external xml:id={(WCB/"a").path.toMD5} own={WCB.path} rev="-1" url={(URLA.toURI/"a").toString} tgt="a" xref={"#"+WCA.path.toMD5}/>
           </wc>
         </registry>))
      (WCB/"a").t must_== SYMLINK
      (WCB/"a").lnktgt must_== Some((WCA/"a").path)      
    }
    "transexs wrt. URL (3rd example)" in {
      setupWC("wca")
      setupWC("wcb")
      setupWC("wce")
      svnUpdate("wcb")
      
      var r = newRegistry()
      r.insert(WCB)
      r.insert(WCE)
      r.sanitize(WCE)
      r.insert(WCA)
      
      svnSetExternal("wcb", (-1, "https://svn.kwarc.info/repos/demos", "a"))
      /* =========================================================================================== */
      /* Here we fake; svnCommit will be locutorCommit */
      svnCommit("wcb", "")
      val exts = new java.util.LinkedList[String]()
      exts.add("https://svn.kwarc.info/repos/demos a")
      r.update(WCB, WCB, exts)
      r.serialize()
      /* =========================================================================================== */
      XML.loadFile(REG) must ==/(
        (<registry version="0.1" xmlns="http://locutor.kwarc.info">
           <wc xml:id={WCA.path.toMD5} url={URLA} root={WCA.path}/>
           <wc xml:id={WCB.path.toMD5} url={URLB} root={WCB.path}>
             <external xml:id={(WCB/"a").path.toMD5} own={WCB.path} rev="-1" url="https://svn.kwarc.info/repos/demos" tgt="a"/>
           </wc>
           <wc xml:id={WCE.path.toMD5} url={URLE} root={WCE.path}>
             <external xml:id={(WCE/"a").path.toMD5} own={WCE.path} rev="-1" url={URLA} tgt="a" xref={"#"+WCA.path.toMD5}/>
           </wc>
         </registry>))
      (WCE/"a").t must_== SYMLINK
      (WCE/"a").lnktgt must_== Some(WCA.path)      
    }
  }


  def resetTransexs = addToSusVerb("reset transexs in case")
  "Update" should resetTransexs {
    "target still exists but differs in revision (1st example)" in {
      setupWC("wca")
      setupWC("wcb")
      setupWC("wce")
      
      val r = newRegistry()
      r.insert(WCB)
      r.insert(WCE)
      r.sanitize(WCE)
      
      svnSetExternal("wcb", (4490, "https://svn.kwarc.info/repos/sandbox/wca", "a"))
      /* =========================================================================================== */
      /* Here we fake; svnCommit will be locutorCommit */
      svnCommit("wcb", "")
      val exts = new java.util.LinkedList[String]()
      exts.add("-r 4490 https://svn.kwarc.info/repos/sandbox/wca a")
      r.update(WCB, WCB, exts)
      r.serialize()
      /* =========================================================================================== */
      XML.loadFile(REG) must ==/(
        (<registry version="0.1" xmlns="http://locutor.kwarc.info">
           <wc xml:id={WCB.path.toMD5} url={URLB} root={WCB.path}>
             <external xml:id={(WCB/"a").path.toMD5} own={WCB.path} rev="4490" url={URLA} tgt="a"/>
           </wc>
           <wc xml:id={WCE.path.toMD5} url={URLE} root={WCE.path}>
             <external xml:id={(WCE/"a").path.toMD5} own={WCE.path} rev="-1" url={URLA} tgt="a"/>
           </wc>
         </registry>))
      (WCE/"a").t must_== NONE
      (WCE/"a") mustNot exist
    }
    "target still exists but differs in revision (2nd example)" in {
      setupWC("wca")
      setupWC("wcb")
      setupWC("wce")
      svnUpdate("wcb")
      
      val r = newRegistry()
      r.insert(WCB)
      r.insert(WCE)
      r.sanitize(WCE)
      
      svnSetExternal("wcb", (-1, "", ""))
      /* =========================================================================================== */
      /* Here we fake; svnCommit will be locutorCommit */      
      svnCommit("wcb", "")
      val exts = new java.util.LinkedList[String]()
      r.update(WCB, WCB, exts)
      r.serialize()
      /* =========================================================================================== */
      XML.loadFile(REG) must ==/(
        (<registry version="0.1" xmlns="http://locutor.kwarc.info">
           <wc xml:id={WCB.path.toMD5} url={URLB} root={WCB.path}/>
           <wc xml:id={WCE.path.toMD5} url={URLE} root={WCE.path}>
             <external xml:id={(WCE/"a").path.toMD5} own={WCE.path} rev="-1" url={URLA} tgt="a"/>
           </wc>
         </registry>))
      
      /*!!! Although external definition of wcb has been removed, the external still exists on the file system
       *    and thus, the dependents can fully be retransformed.
       */
      
      (WCE/"a").t must_== DIRECTORY      
    }
    "target still exists but differs in URL" in {
      setupWC("wca")
      setupWC("wcb")
      setupWC("wce")
      
      val r = newRegistry()
      r.insert(WCB)
      r.insert(WCE)
      r.sanitize(WCE)
      
      svnSetExternal("wcb", (-1, "https://svn.kwarc.info/repos/demos", "a"))
      /* =========================================================================================== */
      /* Here we fake; svnCommit will be locutorCommit */      
      svnCommit("wcb", "")
      val exts = new java.util.LinkedList[String]()
      exts.add("https://svn.kwarc.info/repos/demos a")
      r.update(WCB, WCB, exts)
      r.serialize()      
      /* =========================================================================================== */      
      XML.loadFile(REG) must ==/(
        (<registry version="0.1" xmlns="http://locutor.kwarc.info">
           <wc xml:id={WCB.path.toMD5} url={URLB} root={WCB.path}>
             <external xml:id={(WCB/"a").path.toMD5} own={WCB.path} rev="-1" url="https://svn.kwarc.info/repos/demos" tgt="a"/>
           </wc>
           <wc xml:id={WCE.path.toMD5} url={URLE} root={WCE.path}>
             <external xml:id={(WCE/"a").path.toMD5} own={WCE.path} rev="-1" url={URLA} tgt="a"/>
             </wc>
         </registry>))
      (WCE/"a").t must_== NONE
      (WCE/"a") mustNot exist
    }
  }
}
